from sqlalchemy import Column, Integer, String, DateTime, Unicode
from sqlalchemy import ForeignKey, DECIMAL, Table, LargeBinary
from database import Base
from datetime import datetime

from sqlalchemy.orm import relationship

usuario_rol = Table('usuario_rol', Base.metadata, 
    Column('usuario_id', Integer, ForeignKey('usuario.id')), 
    Column('rol_id', Integer, ForeignKey('rol.id'))
)

miembro = Table('miembro', Base.metadata, 
    Column('proyecto_id', Integer, ForeignKey('proyecto.id')), 
    Column('usuario_id', Integer, ForeignKey('usuario.id'))
)

rol_permiso = Table('rol_permiso', Base.metadata, 
    Column('rol_id', Integer, ForeignKey('rol.id')), 
    Column('permiso_id', Integer, ForeignKey('permiso.id'))
)

lineabase_item = Table('lineabase_item', Base.metadata, 
    Column('lineabase_id', Integer, ForeignKey('lineabase.id')), 
    Column('item_id', Integer, ForeignKey('item.id'))
)

solicitud_item = Table('solicitud_item', Base.metadata, 
    Column('solicitud_id', Integer, ForeignKey('solicitud.id')), 
    Column('item_id', Integer, ForeignKey('item.id'))
)

miembro_comite = Table('miembro_comite', Base.metadata, 
    Column('proyecto_id', Integer, ForeignKey('proyecto.id')), 
    Column('usuario_id', Integer, ForeignKey('usuario.id'))
)

class Usuario(Base):
    __tablename__ = 'usuario'

    id = Column(Integer, primary_key=True)
    id_usuario = Column(String(15), unique=True, nullable=False)
    nombre = Column(String(30), nullable=False)
    apellido = Column(String(30), nullable=False)
    correo = Column(String(30))
    contrasena = Column(Unicode, nullable=False)
    tipo = Column(Integer, nullable=False)
    estado = Column(String, nullable=False)
    fecha_creacion = Column(DateTime)
    usuario_creacion = Column(Integer)
    fecha_modificacion = Column(DateTime)
    usuario_modificacion = Column(Integer)
    roles = relationship('Rol', secondary=usuario_rol,
        backref='usuarios')

class Rol(Base):
    __tablename__ = 'rol'

    id = Column(Integer, primary_key=True)
    nombre = Column(String(15), nullable=False)
    descripcion = Column(String(30))
    observacion = Column(String(30))
    fk_fase = Column(Integer, ForeignKey('fase.id'))
    fecha_creacion = Column(DateTime)
    usuario_creacion = Column(Integer)
    fecha_modificacion = Column(DateTime)
    usuario_modificacion = Column(Integer)
    permisos = relationship('Permiso', secondary=rol_permiso,
        backref='roles')

class Permiso(Base):
    __tablename__ = 'permiso'

    id = Column(Integer, primary_key=True)
    descripcion = Column(String(30))

class Proyecto(Base):
    __tablename__ = 'proyecto'

    id = Column(Integer, primary_key=True)
    nombre = Column(String(15), unique=True, nullable=False)
    descripcion = Column(String(30), nullable=False)
    observacion = Column(String(30))
    presupuesto = Column(DECIMAL, nullable=False)
    estado = Column(String, nullable=False)
    lider = Column(Integer, nullable=False)
    fecha_creacion = Column(DateTime)
    usuario_modificacion = Column(Integer)
    fecha_modificacion = Column(DateTime)
    finalizacion = Column(String)
    fases = relationship('Fase', backref='proyecto',
                                lazy='dynamic')
    miembros = relationship('Usuario', secondary=miembro,
        backref='proyectos')
    miembros_comite = relationship('Usuario', secondary=miembro_comite,
        backref='consejos')

class Fase(Base):
    __tablename__ = 'fase'

    id = Column(Integer, primary_key=True)
    nombre = Column(String(15), nullable=False)
    descripcion = Column(String(30), nullable=False)
    observacion = Column(String(30))
    estado = Column(String, nullable=False)
    fk_proyecto = Column(Integer, ForeignKey('proyecto.id'))
    orden = Column(Integer, nullable=False)
    fecha_creacion = Column(DateTime)
    usuario_creacion = Column(Integer)
    fecha_modificacion = Column(DateTime)
    usuario_modificacion = Column(Integer)
    finalizacion = Column(String)
    roles = relationship('Rol', backref='fase',
                                lazy='dynamic')
    tipos_item = relationship('TipoItem', backref='fase',
                                lazy='dynamic')

class TipoItem(Base):
    __tablename__ = 'tipoitem'

    id = Column(Integer, primary_key=True)
    nombre = Column(String(15), nullable=False)
    descripcion = Column(String(30), nullable=False)
    observacion = Column(String(30))
    fk_fase = Column(Integer, ForeignKey('fase.id'))
    fecha_creacion = Column(DateTime)
    usuario_creacion = Column(Integer)
    fecha_modificacion = Column(DateTime)
    usuario_modificacion = Column(Integer)
    atributos = relationship('Atributo', backref='tipoitem',
                                lazy='dynamic')

class Atributo(Base):
    __tablename__ = 'atributo'

    id = Column(Integer, primary_key=True)
    nombre = Column(String(15), nullable=False)
    descripcion = Column(String(30), nullable=False)
    observacion = Column(String(30))
    tipo = Column(Integer, nullable=False)
    fk_tipo_item = Column(Integer, ForeignKey('tipoitem.id'))
    longitud = Column(Integer)
    precision = Column(Integer)
    obligatorio = Column(String(1), nullable=False)
    fecha_creacion = Column(DateTime)
    usuario_creacion = Column(Integer)
    fecha_modificacion = Column(DateTime)
    usuario_modificacion = Column(Integer)

class Item(Base):
    __tablename__ = 'item'

    id = Column(Integer, primary_key=True)
    nombre = Column(String(15), nullable=False)
    descripcion = Column(String(30), nullable=False)
    observacion = Column(String(30))
    estado = Column(String, nullable=False)
    version = Column(Integer, nullable=False)
    complejidad = Column(Integer, nullable=False)
    costo = Column(DECIMAL, nullable=False)
    fk_tipo_item = Column(Integer, ForeignKey('tipoitem.id'))
    item_anterior = Column(Integer)
    fecha_creacion = Column(DateTime)
    usuario_creacion = Column(Integer)
    fecha_modificacion = Column(DateTime)
    usuario_modificacion = Column(Integer)
    valores = relationship('Valor', backref='item',
                                lazy='dynamic')

class Valor(Base):
    __tablename__ = 'valor'

    id = Column(Integer, primary_key=True)
    fk_item = Column(Integer, ForeignKey('item.id'))
    fk_atributo = Column(Integer, ForeignKey('atributo.id'))
    valor_numerico = Column(DECIMAL)
    valor_cadena = Column(String)
    valor_fecha = Column(DateTime)
    valor_binario = Column(LargeBinary)

class Relacion(Base):
    __tablename__ = 'relacion'

    id = Column(Integer, primary_key=True)
    fk_item_origen = Column(Integer, ForeignKey('item.id'))
    fk_item_destino = Column(Integer, ForeignKey('item.id'))
    estado = Column(String)

class LineaBase(Base):
    __tablename__ = 'lineabase'

    id = Column(Integer, primary_key=True)
    fk_fase = Column(Integer, ForeignKey('fase.id'))
    nombre = Column(String(15), nullable=False)
    estado = Column(String, nullable=False)
    fecha_creacion = Column(DateTime)
    usuario_creacion = Column(Integer)
    items = relationship('Item', secondary=lineabase_item,
        backref='lineabase')

class Solicitud(Base):
    __tablename__ = 'solicitud'

    id = Column(Integer, primary_key=True)
    fk_proyecto = Column(Integer, ForeignKey('proyecto.id'))
    descripcion = Column(String, nullable=False)
    impacto = Column(Integer, nullable=False)
    estado = Column(String, nullable=False)
    votos_a_favor = Column(Integer, nullable=False)
    fecha_creacion = Column(DateTime)
    usuario_creacion = Column(Integer)
    fecha_modificacion = Column(DateTime)
    usuario_modificacion = Column(Integer)
    items = relationship('Item', secondary=solicitud_item,
        backref='solicitud')

class Voto(Base):
    __tablename__ = 'voto'

    id = Column(Integer, primary_key=True)
    fk_solicitud = Column(Integer, ForeignKey('solicitud.id'))
    fk_usuario = Column(Integer, ForeignKey('usuario.id'))
    observacion = Column(String)
    opcion = Column(String(1), nullable=False)
    fecha = Column(DateTime)
